package cn.wjee.gradle.oss.task;

import cn.wjee.commons.collection.MapBuilder;
import cn.wjee.commons.crypto.EncodeUtils;
import cn.wjee.commons.exception.BusinessException;
import cn.wjee.commons.extra.lang.GsonUtils;
import cn.wjee.gradle.oss.config.OssExtConfig;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

import javax.inject.Inject;
import java.util.Map;

/**
 * Publish Task
 *
 * @author listening
 */
public class PublishOssTask extends DefaultTask {
    /**
     * OSS Info
     */
    private final String accessKey;
    private final String accessSecret;
    private final String endpoint;
    private final String bucket;
    /**
     * Source File And Version
     */
    private final String version;
    private final String jarFile;

    /**
     * OSS Save Path And Version txt file
     */
    private final String ossVersionJar;
    private final String ossVersionTxt;

    @Inject
    public PublishOssTask(OssExtConfig config) {
        this.accessKey = config.getAccessKey();
        this.accessSecret = config.getAccessSecret();
        this.endpoint = config.getEndpoint();
        this.version = config.getVersion();
        this.jarFile = config.getJarFile();
        this.bucket = config.getBucket();
        this.ossVersionJar = config.getOssVersionJar();
        this.ossVersionTxt = config.getOssVersionTxt();
    }

    @TaskAction
    public void run() {
        if (uploadJar()) {
            uploadVersion();
        }
    }

    private boolean uploadJar() {
        try {
            Configuration cfg = new Configuration(Region.createWithRegionId("z0"));
            cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
            UploadManager uploadManager = new UploadManager(cfg);
            Auth auth = Auth.create(accessKey, accessSecret);
            String upToken = auth.uploadToken(bucket, ossVersionJar);
            Response response = uploadManager.put(jarFile, ossVersionJar, upToken);
            // parse result
            DefaultPutRet putRet = GsonUtils.fromJson(response.bodyString(), DefaultPutRet.class);
            getLogger().info("[success] => " + putRet.key);
            return true;
        } catch (QiniuException ex) {
            return false;
        }
    }

    private void uploadVersion() {
        try {
            Configuration cfg = new Configuration(Region.createWithRegionId("z0"));
            cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
            UploadManager uploadManager = new UploadManager(cfg);
            Auth auth = Auth.create(accessKey, accessSecret);
            String upToken = auth.uploadToken(bucket, ossVersionTxt);
            Map<String, String> versionMap = MapBuilder
                    .of("version", version)
                    .put("url", endpoint + "/" + ossVersionJar)
                    .ok();
            String json = GsonUtils.toJson(versionMap);
            Response putVersionRes = uploadManager.put(EncodeUtils.getBytes(json), ossVersionTxt, upToken);
            getLogger().info("[publish] =>" + (putVersionRes.isOK() ? "成功" : "失败") + " => " + ossVersionTxt);
        } catch (QiniuException ex) {
            throw new BusinessException("uploadVersion fail", ex);
        }
    }
}
